﻿
namespace MyFurion.Application
{
    /// <summary>
    /// 机构仓储
    /// </summary>
    public class OrgRepository:BaseRepository<OrgInfo>,ITransient
    {
        /// <summary>
        /// 查询条件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private Expression<Func<OrgInfo, bool>> GetCodition(OrgInfoPage input)
        {
            var exp = Expressionable.Create<OrgInfo>();
            exp.AndIF(!string.IsNullOrWhiteSpace(input.OrgCode), it => it.OrgCode.Contains(input.OrgCode));
            exp.AndIF(!string.IsNullOrWhiteSpace(input.OrgName), it => it.OrgName.Contains(input.OrgName));
            return exp.ToExpression();
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<OrgInfo>> GetPageList(OrgInfoPage input)
        {
            var whereExp = GetCodition(input);
            return await GetPageListAsync(whereExp, input.PageIndex, input.PageSize, it => it.CreateTime);
        }
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<OrgInfo>> GetDataList(OrgInfoPage input)
        {
            var exp = GetCodition(input);
            return await GetList(exp, it=>it.SortNum, OrderByType.Asc);
        }
        /// <summary>
        /// 获取树数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<OrgInfo>> GetTreeData()
        {
            return await Context.Queryable<OrgInfo>().OrderBy(p => p.SortNum).ToTreeAsync(p => p.Children, p =>p.ParentId, null);
        }
        /// <summary>
        /// 根据查询条件获取树结构数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<OrgInfo>> GetTree(OrgInfoPage input)
        {
            bool isNotFilter = ToolUtil.IsPropNull(input, new List<string>() { "PageIndex", "PageSize", "StartTime", "EndTime" });
            if (isNotFilter)
            {
                return await GetTreeData();
            }
            else
            {
                var exp = GetCodition(input);
                var ids = await Context.Queryable<OrgInfo>().Where(exp).Select(p => p.Id).ToListAsync();
                var inIds = ids.Cast<object>().ToArray();
                return await Context.Queryable<OrgInfo>().OrderBy(p => p.SortNum).ToTreeAsync(p => p.Children, p => p.ParentId, null, inIds);
            }
        }
        /// <summary>
        /// 根据父级id获取数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<OrgInfo>> GetByParentId(long pid)
        {
            return await GetList(it=>it.ParentId==pid, it=>it.SortNum, OrderByType.Asc);
        }
        /// <summary>
        /// 是否空表
        /// </summary>
        /// <returns></returns>
        public async Task<bool> IsEmptyData()
        {
            int count = await Context.Queryable<OrgInfo>().Filter(null, true).CountAsync();
            return count == 0;
        }
        /// <summary>
        /// 数据是否存在
        /// </summary>
        /// <param name="orgCode"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DataExists(string orgCode, long? id = null)
        {
            return await Context.Queryable<OrgInfo>()
                .Where(it => it.OrgCode == orgCode)
                .WhereIF(id.HasValue, it => it.Id != id.Value)
                .AnyAsync();
        }
        /// <summary>
        /// 根据角色id获取机构权限集合
        /// </summary>
        /// <param name="roleid"></param>
        /// <returns></returns>
        public async Task<List<OrgInfo>> GetRoleOrgPer(long roleid)
        {
            var orgTree = await GetTreeData();
            var roleOrgIds = await App.GetService<OrgPerRepository>().GetRoleOrgIds(new List<long> { roleid });
            if (roleOrgIds.Any())
            {
                SetIsPer(orgTree, roleOrgIds);
            }
            return orgTree;
        }
        /// <summary>
        /// 遍历机构树节点，设置角色机构权限
        /// </summary>
        /// <param name="orgTree"></param>
        /// <param name="orgPerIds"></param>
        private void SetIsPer(List<OrgInfo> orgTree, List<long> orgPerIds)
        {
            foreach (var org in orgTree)
            {
                org.IsRolePer = orgPerIds.Any(g => org.Id == g);
                SetIsPer(org.Children, orgPerIds);
            }
        }
    }
}
